﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using JOUtils.SpotifyTalker;
using System.Text.RegularExpressions;

namespace Screenify
{
    public partial class MainForm : Form
    {        
        
        #region Preview API's

        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect);

        #endregion

        bool IsPreviewMode = false;

        #region Constructors

        public MainForm()
        {
            InitializeComponent();
        }

        //This constructor is passed the bounds this form is to show in
        //It is used when in normal mode
        public MainForm(Rectangle Bounds)
        {
            InitializeComponent();
            this.Bounds = Bounds;
            //hide the cursor
            Cursor.Hide();
        }

        //This constructor is the handle to the select screensaver dialog preview window
        //It is used when in preview mode (/p)
        public MainForm(IntPtr PreviewHandle)
        {
            InitializeComponent();

            //set the preview window as the parent of this window
            SetParent(this.Handle, PreviewHandle);

            //make this a child window, so when the select screensaver dialog closes, this will also close
            SetWindowLong(this.Handle, -16, new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000));

            //set our window's size to the size of our window's new parent
            Rectangle ParentRect;
            GetClientRect(PreviewHandle, out ParentRect);
            this.Size = ParentRect.Size;

            //set our location at (0, 0)
            this.Location = new Point(0, 0);

            IsPreviewMode = true;
        }

        #endregion

        #region GUI

        //sets up the screen saver
        private void MainForm_Shown(object sender, EventArgs e)
        {
            if (!IsPreviewMode) //we don't want all those effects for just a preview
            {
                this.Refresh();
            }
            //change the back color to a lovely shade of total blackness
            this.BackColor = Color.FromArgb(0, 0, 0);

            SpotifyTalker _talker = new SpotifyTalker();

            try 
	        {	        
        		_talker.Initialize();
                _talker.OnSpotifyTrackChanged += new SpotifyTalker.SpotifyTrackChangedHandler(OnSpotifyTrackChanged);


                //Let's set the label to the window title of Spotify.
                labelScreenify.Text = _talker.CurrentWindowTitle.Split('-')[1];
	        }
	        catch (Exception ex)
	        {
                MessageBox.Show(
                    this,
                    ex.Message,
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
	        }
        }

        private void OnSpotifyTrackChanged(object sender, SpotifyTrackChangedEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new SpotifyTalker.SpotifyTrackChangedHandler(this.OnSpotifyTrackChanged), sender, e);
            }
            else
            {
                GenerateScreenify(e.Artist, e.Track);
            }
        }

        //generates a BSOD bitmap with a random error and a random file name gathered from the "Errors" class
        private void GenerateScreenify(string artist, string track)
        {
            if (IsPreviewMode)
            {
                labelScreenify.Text = artist + " - " + track;
            }
            else
            {
                labelScreenify.Text = artist + " - " + track;
            }
        }

        #endregion

        #region User Input

        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (!IsPreviewMode) //disable exit functions for preview
            {
                Application.Exit();
            }
        }

        private void MainForm_Click(object sender, EventArgs e)
        {
            if (!IsPreviewMode) //disable exit functions for preview
            {
                Application.Exit();
            }
        }

        //start off OriginalLoction with an X and Y of int.MaxValue, because
        //it is impossible for the cursor to be at that position. That way, we
        //know if this variable has been set yet.
        Point OriginalLocation = new Point(int.MaxValue, int.MaxValue);

        private void MainForm_MouseMove(object sender, MouseEventArgs e)
        {
            if (!IsPreviewMode) //disable exit functions for preview
            {
                //see if originallocat5ion has been set
                if (OriginalLocation.X == int.MaxValue & OriginalLocation.Y == int.MaxValue)
                {
                    OriginalLocation = e.Location;
                }
                //see if the mouse has moved more than 20 pixels in any direction. If it has, close the application.
                if (Math.Abs(e.X - OriginalLocation.X) > 20 | Math.Abs(e.Y - OriginalLocation.Y) > 20)
                {
                    Application.Exit();
                }
            }
        }

        #endregion
    }
}
